package cn.zxh.csdn_maven.atomy.auth;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import cn.zxh.csdn_maven.base.pojo.Cookies;
import cn.zxh.csdn_maven.base.pojo.User;
import cn.zxh.csdn_maven.work.flow.login.WorkFlowde;

/**
 * 处理CSDN登录问题
 * 
 * @author zhangxinhua
 *
 */
@SuppressWarnings(value={"unused","deprecation"})
public class Login {

	private Logger logger = Logger.getLogger(Login.class);
	/** 模拟请求的工具类 */
	private HttpClient client = null;
	/** 用户信息 */
	private User user = null;
	/** 登录地址 */
	private String loginUrl = "https://passport.csdn.net/account/verify";

	public Login(User user) {
		this.user = user;
		client = new DefaultHttpClient();
	}

	public Map<String, Object> getHiddenMap() throws ClientProtocolException, IOException {
		Map<String, Object> params=new HashMap<String, Object>();
		Map<String, Object> map = WorkFlowde.getInstance().startExec(client, params);
		return map;
	}
	/**
	 * 获取表单的额外数据
	 * 
	 * @throws IOException
	 * @throws ClientProtocolException
	 */
	public List<NameValuePair> getHiddenData() throws ClientProtocolException, IOException {
		List<NameValuePair> hiddenParams = new ArrayList<NameValuePair>();
		Map<String, Object> map = getHiddenMap();
		// Cookies.setTicket(hiddens.get(0).attr("value"));
		for (Entry<String, Object> entry : map.entrySet()) {
			hiddenParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
		}
		//修改请求地址
		loginUrl=map.get("action").toString();
		return hiddenParams;
	}

	/**
	 * 开始验证登录
	 * 
	 * @return
	 * @throws IOException
	 * @throws ClientProtocolException
	 */
	public boolean start() throws ClientProtocolException, IOException {
		/** 默认登录失败 */
		boolean flag = false;
		/** 获取隐藏数据 */
		List<NameValuePair> params = getHiddenData();
		// 登录用到post请求，这里用post
		HttpPost httpPost = new HttpPost(loginUrl);
		params.add(new BasicNameValuePair("rememberMe", "true"));
		params.add(new BasicNameValuePair("username", user.getEamil()));
		params.add(new BasicNameValuePair("password", user.getPassword()));
		httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
		/** 添加请求头信息 */
		httpPost.setHeader("Cookie", Cookies.getCookies());
		HttpResponse httpResponse = client.execute(httpPost);
		/**设置cookie*/
		Cookies.setCookies(httpResponse.getHeaders("Set-Cookie"));
		String html = EntityUtils.toString(httpResponse.getEntity());
		httpPost.releaseConnection();
		Document document = Jsoup.parse(html);
		Element errorMsg = document.getElementById("error-message");
		// CSDN登陆成功会有redirect_back这个函数在脚本中执行放行
		if (html.indexOf("redirect_back") > 0) {
			logger.info("----------------登录成功----------------");
			flag = true;
		} else if (errorMsg != null) {
			logger.info("服务器异常1" + errorMsg.html());
			if (errorMsg.html().indexOf("登录太频繁") >= 0) {
//				logger.info("sleep " + LOGIN_WIAT_TIME + " s  ...");
//				Sleep.sleep(LOGIN_WIAT_TIME);
			}
		} else if (html.indexOf("服务器") > 0) {
			logger.info("----------------服务器异常----------------");
			flag = false;
		} else {
			logger.info("----------------登录失败----------------");
			flag = false;
		}
		return flag;
	}
	
	/**
	 * 如何获取cookie
	 * 在login界面中结尾处有publib_footer.js？+ Math.floor(new Date()/120000).toString(36)
	 * 在publib-footer.js中引入tracking.js?v=' + Math.random()
	 * 在tracking.js中有我们需要的cookie设置
	 * 设置完成之后再https://dc.csdn.net/track?5455=&user_name=&x-acl-token=status_js_dkuyqthzbajmncbsb_token&pid=passport&oid=&referrer=&tos=-86463335901740&session_id=1507857353482_0.020226516994955146
	 * 界面中响应头中有uuid-tt-dd的cookie属性
	 */
}
